home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / dec92.zip / 1012051A < prev    next >
Text File  |  1992-10-09  |  8KB  |  379 lines

  1. /*EM    BOGUS.C - Bogus Device Driver DLL
  2.  *
  3.  *    SUMMARY
  4.  *        Basic LibMain and WEP functions
  5.  *
  6.  *    COMMENTS
  7.  *
  8.  *    WARNINGS
  9.  *
  10.  */
  11.  
  12.  
  13. #include <windows.h>
  14. #include "bogusa.h"
  15. #include "pic.h"
  16. #include "dpmi.h"
  17.  
  18. #define EXPORT _export _loadds
  19. #include "bogus.h"
  20.  
  21. #define FAKE_PORT    0x141  /* Bogosity Level =  9.4 */
  22. #define FAKE_IRQ    11     /* Bogosity Level =  9.8 */
  23.  
  24. #define FAKE_CTL_START    0x01   /* bogus port start command (set to zero) */
  25. #define FAKE_CTL_EOI    0x02   /* bogus port EOI (set to zero) */
  26.  
  27. #define FAKE_STAT_BUSY    0x01   /* bogus port busy indication (zero=>busy) */
  28. #define FAKE_STAT_IRQ    0x02   /* bogus port IRQ (zero=>IRQ) */
  29. #define FAKE_STAT_ERROR 0x04   /* I/O error (zero=>error) (cleared on read) */
  30.  
  31.  
  32. /* Set variables for our interrupt number */
  33.  
  34. #if (FAKE_IRQ < 8)
  35. #define INT_DEV (INT_MASTER_0+(FAKE_IRQ & 7))
  36. #define PIC00 INTA00
  37. #define PIC01 INTA01
  38. #else
  39. #define INT_DEV (INT_SLAVE_0+(FAKE_IRQ & 7))
  40. #define PIC00 INTB00
  41. #define PIC01 INTB01
  42. #endif
  43. #define INT_MASK (1 << (FAKE_IRQ & 7))
  44.  
  45.  
  46. BOOL FAR PASCAL LibMain(HANDLE hInstance   /* Library instance handle  */
  47.                ,WORD wDataSeg        /* Default data segment    */
  48.                ,WORD cbHeap        /* Default Heap size    */
  49.                ,LPSTR lpszCmdLine) ;/* Command line        */
  50. int FAR PASCAL WEP(int fSystemExit) ;
  51. #pragma alloc_text(INIT_TEXT,LibMain)    /* Keep this with LIBENTRY.ASM    */
  52. #pragma alloc_text(FIXED_TEXT,WEP)
  53.  
  54. HANDLE hLibInstance ;
  55. FARPROC lpfnPrevISR ;        /* Saved Previous ISR */
  56. DWORD lpfnPrevRMISR ;        /* Saved Previous real-mode ISR */
  57. HANDLE hReflector ;
  58.  
  59. DWORD DPMI_AllocateRMCallback(FARPROC lpfnCallback, _RMCS FAR *lpRMCS)
  60. {
  61.     DWORD dwRet ;
  62.     _asm {
  63.     push    ds
  64.     lds    si,lpfnCallback
  65.     les    di,lpRMCS
  66.     mov    ax,DPMI_ALLOCRMC
  67.     int    IVEC_DPMI
  68.     pop    ds
  69.     jc    lbl1
  70.     mov    word ptr dwRet,dx     ; return callback address
  71.     mov    word ptr dwRet+2,cx
  72.     jmp    short lbl2
  73. lbl1:
  74.     mov    word ptr dwRet,ax     ; error code in ax
  75.     mov    word ptr dwRet+2,0     ; return seg=0 if error
  76. lbl2:
  77.     }
  78.  
  79.     return dwRet ;
  80. }
  81.  
  82.  
  83. WORD DPMI_FreeRMCallback(DWORD lpfnCallback)
  84. {
  85.     WORD wRet ;
  86.  
  87.     _asm {
  88.     mov    dx,word ptr lpfnCallback
  89.     mov    cx,word ptr lpfnCallback+2
  90.     mov    ax,DPMI_FREERMC
  91.     int    IVEC_DPMI
  92.     jc    lbl1
  93.     xor    ax,ax
  94. lbl1:
  95.     mov    wRet,ax
  96.     }
  97.     return wRet ;
  98. }
  99.  
  100.  
  101. DWORD DPMI_GetRMVector(int iVector)
  102. {
  103.     DWORD dwRet ;
  104.     _asm {
  105.     mov    ax,DPMI_GETRMVEC
  106.     mov    bl,byte ptr iVector
  107.     int    31h
  108.     mov    word ptr dwRet,dx
  109.     mov    word ptr dwRet+2,cx
  110.     }
  111.     return dwRet ;
  112. }
  113.  
  114.  
  115. void DPMI_SetRMVector(int iVector, DWORD lpfnRMISR)
  116. {
  117.     _asm {
  118.     mov    ax,DPMI_SETRMVEC
  119.     mov    bl,byte ptr iVector
  120.     mov    dx,word ptr lpfnRMISR
  121.     mov    cx,word ptr lpfnRMISR+2
  122.     int    31h
  123.     }
  124. }
  125.  
  126.  
  127. FARPROC GetPMVector(int iVector)
  128. {
  129.     FARPROC dwRet ;
  130.  
  131.     _asm {
  132.     mov    al,byte ptr iVector
  133.     mov    ah,35h
  134.     int    21h
  135.     mov    word ptr dwRet,bx
  136.     mov    word ptr dwRet+2,es ; Save it
  137.     }
  138.     return dwRet ;
  139. }
  140.  
  141.  
  142. void SetPMVector(int iVector, FARPROC lpfnISR)
  143. {
  144.     _asm {
  145.     push    ds
  146.     lds    dx,lpfnISR
  147.     mov    al,byte ptr iVector
  148.     mov    ah,25h
  149.     int    21h            ; Set our ISR
  150.     pop    ds
  151.     }
  152. }
  153.  
  154.  
  155. HANDLE AllocIntReflector(int iVector, FARPROC lpfnCallback)
  156. {
  157.     DWORD dwDosMem ;
  158.     LPSTR lpLowRMISR ;
  159.     DWORD lpfnRMCallback ;
  160.     _RMCS FAR *lpSaveRegs ;
  161.  
  162.     /* Allocate some DOS memory for the Real-mode Interrupt service routine */
  163.  
  164.     dwDosMem = GlobalDosAlloc(16 + sizeof (int) + sizeof (_RMCS)) ;
  165.  
  166.     if (dwDosMem == 0)
  167.     return 0 ;
  168.     lpLowRMISR = (LPSTR) MAKELONG(0,LOWORD(dwDosMem)) ;
  169.     lpSaveRegs = (_RMCS FAR *) (&lpLowRMISR[16]) ;
  170.  
  171.     /* Allocate a real-mode callback */
  172.  
  173.     lpfnRMCallback = DPMI_AllocateRMCallback((FARPROC)lpfnCallback,lpSaveRegs)
  174. ;
  175.     if (HIWORD((DWORD)lpfnRMCallback) == 0)
  176.     {
  177.     GlobalDosFree(LOWORD(dwDosMem)) ;
  178.     return 0;
  179.     }
  180.  
  181.     /* Generate the low-memory code (it's only 6 bytes) */
  182.  
  183.     lpLowRMISR[0] = 0x9A ;        /* CALL FAR PTR */
  184.     *((DWORD FAR *)&(lpLowRMISR[1])) = lpfnRMCallback ;
  185.     lpLowRMISR[5] = 0xCF ;        /* IRET */
  186.     *((int FAR *)&(lpLowRMISR[6])) = iVector ;
  187.  
  188.     /* hook the real mode interrupt vector */
  189.     DPMI_SetRMVector(iVector,MAKELONG(0,HIWORD(dwDosMem))) ;
  190.  
  191.     return (HANDLE) LOWORD(dwDosMem) ;    /* return the reflector handle */
  192. }
  193.  
  194.  
  195. void FreeIntReflector(HANDLE hReflector)
  196. {
  197.     LPSTR lpLowRMISR ;
  198.     DWORD lpfnRMCallback ;
  199.  
  200.     /* Get the protected mode address of the low ISR */
  201.  
  202.     lpLowRMISR = (LPSTR)MAKELONG(0,(WORD)hReflector) ;
  203.  
  204.  
  205.     /* make sure that it's a reflector */
  206.     if ((lpLowRMISR[0] != 0x9A) || (lpLowRMISR[5] != 0xCF))
  207.     return ;    /* exit if not a reflector */
  208.  
  209.  
  210.     /* Extract the callback address and free the callback */
  211.  
  212.     lpfnRMCallback = *((DWORD FAR *)&(lpLowRMISR[1])) ;
  213.     DPMI_FreeRMCallback(lpfnRMCallback) ;
  214.  
  215.  
  216.     /* free the real-mode interrupt service routine */
  217.  
  218.     GlobalDosFree((WORD) hReflector) ;
  219. }
  220.  
  221.  
  222. /*XP<    LibMain - Main library entry point.
  223.  *
  224.  *    ENTRY
  225.  *
  226.  *    EXIT
  227.  *
  228.  *    RETURNS
  229.  *        TRUE if initialization succeeds, FALSE otherwise.
  230.  *
  231.  *    WARNINGS
  232.  *
  233.  *    CALLS
  234.  *
  235.  *    NOTES
  236.  *        The true library entry point is in the assembly language
  237.  *        module LIBENTRY.ASM, but it simply passes control to here.
  238.  *
  239.  */
  240. BOOL FAR PASCAL LibMain(HANDLE hInstance   /* Library instance handle  */
  241.                ,WORD wDataSeg        /* Default data segment    */
  242.                ,WORD cbHeap        /* Default Heap size    */
  243.                ,LPSTR lpszCmdLine)  /* Command line        */
  244. /*>*/
  245. {
  246.     lpszCmdLine = lpszCmdLine ;     /* Avoid -W4 warnings        */
  247.      wDataSeg = wDataSeg ;
  248.      cbHeap = cbHeap ;
  249.      hLibInstance = hInstance ;        /* We may need this later to access
  250.                        resources from our executable    */
  251.  
  252.  
  253.     return TRUE ;
  254. }
  255.  
  256.  
  257.  
  258. /*XP<    WEP - Windows Exit Procedure
  259.  *
  260.  *    ENTRY
  261.  *        fSystemExit indicates if we are terminating the Windows
  262.  *        session.  Otherwise, we are only unloading this DLL.
  263.  *
  264.  *    RETURNS
  265.  *        Always returns "1".
  266.  *
  267.  *    WARNINGS
  268.  *        Due to bugs in Windows 3.0 and earlier (and perhaps later),
  269.  *        this function must be placed in a fixed segment.  This same
  270.  *        bug makes the value of DS questionable, so we cannot use it
  271.  *        (or any static data).
  272.  *
  273.  *        To be sure, we don't do anything here, anyway.
  274.  *
  275.  *    CALLS
  276.  *        None
  277.  *
  278.  *    NOTES
  279.  *        This is the standard DLL exit procedure.
  280.  *
  281.  */
  282. int FAR PASCAL WEP(int fSystemExit)
  283. /*>*/
  284. {
  285.     fSystemExit = fSystemExit ;     /* Avoid -W4 warning        */
  286.     return 1 ;                /* Always indicate success        */
  287. }
  288.  
  289.  
  290. int EXPORT FAR PASCAL BogusCheck(void)
  291. {
  292.     BYTE bPortVal ;
  293.  
  294.     _asm {
  295.     mov    dx,FAKE_PORT
  296.     in    al,dx            ; Is the bogus device present ?
  297.     mov    bPortVal,al
  298.     }
  299.  
  300.     return ((bPortVal & 0x80) == 0) ; /* Return TRUE if device is present */
  301. }
  302.  
  303.  
  304. void EXPORT FAR PASCAL BogusStart(HWND hWnd, WPARAM wParam)
  305. {
  306.     wParamEvent = wParam ;
  307.     hWndEvent = hWnd ;
  308.  
  309.     if (!lpfnPrevISR)
  310.     {
  311.     /* Save the previous ISR and set ours */
  312.     _asm cli
  313.     lpfnPrevISR = GetPMVector(INT_DEV) ;
  314.     SetPMVector(INT_DEV,(FARPROC)IntSvcRtn) ;
  315.     _asm sti
  316.  
  317.     /* Save the previous real mode ISR and reflect to ours */
  318.     lpfnPrevRMISR = DPMI_GetRMVector(INT_DEV) ;
  319.     hReflector = AllocIntReflector(INT_DEV,(FARPROC)BogusCallback) ;
  320.  
  321.     /* Unmask the interrupt and begin device I/O */
  322.     _asm {
  323.         cli
  324.         in        al,PIC01        ; unmask the interrupt
  325.         and     al,NOT INT_MASK
  326.         out     PIC01,al
  327.         sti
  328.         mov     al,NOT FAKE_CTL_START
  329.         mov     dx,FAKE_PORT
  330.         out     dx,al        ; start device I/O
  331.         }
  332.     }
  333. }
  334.  
  335.  
  336. int EXPORT FAR PASCAL BogusGetEvent(void)
  337. {
  338.     WORD wCountRet ;
  339.  
  340.     _asm {
  341.     mov    ax,SEG wCount
  342.     mov    es,ax
  343.     xor    ax,ax
  344.     xchg    ax,es:wCount        ; get count, set to zero
  345.     mov    wCountRet,ax
  346.     }
  347.  
  348.     return wCountRet ;
  349. }
  350.  
  351.  
  352. void EXPORT FAR PASCAL BogusStop(void)
  353. {
  354.     hWndEvent = 0x0000 ;    /* Tell the ISR to stop */
  355.  
  356.     if (!lpfnPrevISR)
  357.     return ;        /* return if not started */
  358.  
  359.     _asm {
  360.     mov    dx,FAKE_PORT
  361. l1:
  362.     in    al,dx
  363.     rcr    al,1
  364.     jnc    l1          ; loop while busy
  365.  
  366.     cli
  367.     in    al,PIC01
  368.     or    al,INT_MASK
  369.     out    PIC01,al        ; mask the interrupt level
  370.     sti
  371.     }
  372.  
  373.     DPMI_SetRMVector(INT_DEV, lpfnPrevRMISR) ;     /* Restore real-mode vector */
  374.     FreeIntReflector(hReflector) ;         /* Free the reflector */
  375.     SetPMVector(INT_DEV, lpfnPrevISR) ;      /* Restore the prot-mode vector */
  376.  
  377.     lpfnPrevISR = NULL ;
  378. }
  379.